package com.openess.bigsearch.engine.analyzer;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import ICTCLAS.I3S.AC.ICTCLAS50;

import com.openess.bigsearch.engine.index.Token;
import com.openess.bigsearch.engine.utils.LinkedList;

/**
 * 采用了中科院的中文分词器
 * 
 * @author TuTu
 * 
 */
public class ICTAnalyzer implements Analyzer {
	// 停用词列表，忽略大小写，停用词对效率影响挺大的，一方面降低了分词效率，即索引效率，但另一方面又提高了检索效率

	public static final String[] stopTerm = { "了", "的", "哦", "啊", "啦", "a",
			"an", "and", "or", "as", "for", "the", "that", "those", "over",
			"under", "above", "below" };

	/**
	 * ICT分词器
	 */
	private ICTCLAS50 ict;

	/**
	 * 默认构造方法
	 */
	public ICTAnalyzer() {
		ict = new ICTCLAS50();
		String path = System.getProperty("user.dir")
				+ "\\src\\com\\openess\\bigsearch\\engine\\ICTCLAS\\";
		// System.out.println(path);
		// 分词器的初始化
		ict.ICTCLAS_Init(path.getBytes());
	}

	@Override
	public Token<String, Integer>[] parse(int offset, String str) {
		if (str == null || str.length() == 0) {
			return null;
		}
		// 过滤掉的空格数
		int num = -1;
		byte[] temp = ict.ICTCLAS_ParagraphProcess(str.getBytes(), 0, 0);
		// 不过滤头尾空格，全部小写化，过滤头尾空格有问题，可能造成偏移位置错位
		String input = new String(temp, 0, temp.length).toLowerCase();
		// 不应该所有符号的过滤工作都交给正则表达式，主要的分法应该由分词器来控制，自己写的正则应该只用在过滤单独分出来的符号中
		String regex = "\\s+[^\\u4e00-\\u9fa5\\w]+\\s+|\\s+";
		Pattern pattern = Pattern.compile(regex);
		Matcher m = pattern.matcher(input);
		// 集合用于装载分割后的子串即每个子串的起始位置
		LinkedList<Token<String, Integer>> list = new LinkedList<Token<String, Integer>>();
		// 待分割子串的起始位置
		int index = 0;
		// 循环分割
		while (m.find()) {
			// 分割
			String match = input.substring(index, m.start());
			// 截取超过指定长度的分词
			if (match.length() > TERMLENGTH)
				match = match.substring(0, TERMLENGTH);
			num++;
			// 分割出空串不放入集合，属于停用词不放入集合
			if (match.length() != 0 && !isStop(match)) {
				list.add(new Token<String, Integer>(match, index + offset - num));
			}
			index = m.end();
		}
		// 保存最后一段分割子串
		String match = input.substring(index, input.length());
		if (match.length() > TERMLENGTH)
			match = match.substring(0, TERMLENGTH);
		if (match.length() != 0) {
			list.add(new Token<String, Integer>(match, index + offset - num));
		}
		if (list.size() == 0)
			return null;
		// 将结合转换为数组返回
		return list.toArray(new Token<String, Integer>());
	}

	/**
	 * 停用词过滤，如果参数属于停用词的一种，那么返回true，否则返回false
	 * 
	 * @param str
	 * @return
	 */
	private boolean isStop(String str) {
		for (String stop : stopTerm) {
			if (stop.equalsIgnoreCase(str)) {
				return true;
			}
		}
		return false;
	}
}
